<script>
  /*
 * @Author: LiYu
 * @Date: 2022-04-05 14:38:31
 * @LastEditors: LiYu
 * @LastEditTime: 2022-04-05 16:00:13
 * @Description: 发布订阅
 */
  class Emitter {
    listenerSet = {};

    on(name, callback) {
      const listeners = this.listenerSet[name] || [];
      listeners.push(callback);
      this.listenerSet[name] = listeners;
    }

    emit(name, ...args) {
      const listeners = this.listenerSet[name];
      if (listeners) {
        listeners.forEach(listener => {
          listener.apply(this, args);
        })
      } else {
        console.warn(`无监听者: ${name}`);
      }
    }

    off(name, fn) {
      const listener = this.listenerSet[name];
      if (listener) {
        const idx = listener.findIndex(callback => callback === fn);
        if (idx >= 0) {
          listener.splice(idx, 1);
        }
      } else {
        console.warn(`无监听者: ${name}`);
      }
    }

    once(name, callback) {
      const fn = (...args) => {
        callback.apply(this, args);
        this.off(name, fn);
      }
      this.on(name, fn);
    }
  }


  
  // test
  const emitter = new Emitter();

  emitter.on('post', (value) => {
    console.log('on', value);
  })

  emitter.on('post', callback)

  function callback(...args) {
    console.log('on', args);
  }

  emitter.off('post', callback);

  emitter.once('post', (...args) => {
    console.log('once', args);
  })

  emitter.emit('post', 1, 2, 3);

</script>